package com.vcare.screw;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

public class MainController implements Initializable{

	@FXML
	private Button testCon;
	
	@FXML
	private Button exportWord;
	
	@FXML
	private ChoiceBox<String> dbType;
	@FXML
	private ChoiceBox<String> outType;
	
	@FXML
	private TextField username;
	
	@FXML
	private TextField port;
	
	@FXML TextField host;
	
	@FXML
	private PasswordField password;
	
	@FXML
	private Label dirPath;
	
	@FXML
	private Button choisePath;
	
	@FXML
	private ImageView img;
	
	@FXML
	private TextField dbName;
	
	@FXML
	private Label dbLabel;
	//数据源
	DataSource dataSource;
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		dbType.setItems(FXCollections.observableArrayList("mysql","oracle"));
		dbType.getSelectionModel().select(0);
		outType.setItems(FXCollections.observableArrayList("html","doc","md"));
		outType.getSelectionModel().select(0);
		Image image = new Image("/head_2.jpg");
		img.setImage(image);
		host.setText("127.0.0.1");
		port.setText("3306");
		username.setText("root");
		password.setText("12345678");
		dbName.setText("fmmp_stats");
		dbType.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
			@Override
			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
				if("mysql".equals(newValue)){
					dbName.setVisible(true);
					dbLabel.setVisible(true);
				}else if("oracle".equals(newValue)){
					dbName.setVisible(false);
					dbLabel.setVisible(false);
				}
			}
		});
	}
	
	public boolean initdb(){
		boolean bl=false;
		String type = dbType.getValue();
		String user = username.getText();
		String pwd = password.getText();
		String db = dbName.getText();
		String p = port.getText();
		String h = host.getText();
		HikariConfig hikariConfig = new HikariConfig();
		if("mysql".equals(type)){
			hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
			hikariConfig.setJdbcUrl("jdbc:mysql://"+h+":"+p+"/"+db+"?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8");
			hikariConfig.setUsername(user);
			hikariConfig.setPassword(pwd);
			//设置可以获取tables remarks信息
			hikariConfig.addDataSourceProperty(db, "true");
			hikariConfig.setMinimumIdle(2);
			hikariConfig.setMaximumPoolSize(5);
		}else if("oracle".equals(type)){
			hikariConfig.setDriverClassName("oracle.jdbc.driver.OracleDriver");
			hikariConfig.setJdbcUrl("jdbc:oracle:thin:@"+h+":"+p+":"+db+"");
			hikariConfig.setUsername(user);
			hikariConfig.setPassword(pwd);
			//设置可以获取tables remarks信息
			hikariConfig.addDataSourceProperty(db, "true");
			hikariConfig.setMinimumIdle(2);
			hikariConfig.setMaximumPoolSize(5);
		}
		try {
			dataSource = new HikariDataSource(hikariConfig);
			bl=true;
		} catch (Exception throwables) {
			throwables.printStackTrace();
			Alerts(false,"连接数据库异常，请检查！");
		}

		return bl;
	}

	public void reconn(ActionEvent event){
		initdb();
	}
	
	public void selectDirPath(ActionEvent event){
		Stage mainStage = null;
		DirectoryChooser directory = new DirectoryChooser();
		directory.setTitle("选择路径");
		File file = directory.showDialog(mainStage);
		if(file!=null){
			String path = file.getPath();
			dirPath.setText(path);			
		}
	}
	
	public void typeTouch(MouseEvent event){
		String value = dbType.getValue();
		System.out.println(value);
		if(value.equals("mysql")){
			dbName.setVisible(true);
		}
		if(value.equals("oracle")){
			dbName.setVisible(false);
		}
	}
	
	public void testCon(ActionEvent event) throws SQLException {
		isCon();
	}
	
	public boolean isCon() throws SQLException {
		String type = dbType.getValue();
		initdb();
		Connection con = null;
		if("mysql".equals(type)){
			con = dataSource.getConnection();
			if(con!=null){
				Alerts(true,"connected to database success");
				return true;
			}else{
				Alerts(false,"connecting to database failed");
				return false;
			}
		}
		if("oracle".equals(type)){
			con = dataSource.getConnection();
			if(con!=null){
				Alerts(true,"connected to database success");
				return true;
			}else{
				Alerts(false,"connecting to database failed");
				return false;
			}
		}
		return false;
	}
	
	public void exportDoc(ActionEvent event){
		String type = dbType.getValue();
		String user = username.getText();
		String pwd = password.getText();
		String dir = dirPath.getText();
		String value = dbName.getText();
		String outTypeValue = outType.getValue();
		String p = port.getText();
		String h = host.getText();
		if(dir.equals("未选择")){
			Alerts(false, "请选择文件路径");
			return;
		}
		Map<String,String> map = new HashMap<String,String>();
		map.put("-t", type);
		map.put("-u", user);
		map.put("-p", pwd);
		map.put("-d", dir);
		map.put("-n", value);
		map.put("p",p);
		map.put("h",h);


		boolean b = check(map);
		if(!b){
			return ;
		}


		if(!initdb()){
			return;
		}

		EngineFileType fileType=null;
		if("html".equals(outTypeValue)){
			fileType=EngineFileType.HTML;
		}else if("doc".equals(outTypeValue)){
			fileType=EngineFileType.WORD;
		}else if("md".equals(outTypeValue)){
			fileType=EngineFileType.MD;
		}
		//生成配置
		EngineConfig engineConfig = EngineConfig.builder()
				//生成文件路径
				.fileOutputDir(dir)
				//打开目录
				.openOutputDir(true)
				//文件类型
				.fileType(fileType)
				//生成模板实现
				.produceType(EngineTemplateType.freemarker).build();

		//忽略表
		ArrayList<String> ignoreTableName = new ArrayList<>();
		ignoreTableName.add("test_user");
		ignoreTableName.add("test_group");
		//忽略表前缀
		ArrayList<String> ignorePrefix = new ArrayList<>();
		ignorePrefix.add("test_");
		//忽略表后缀
		ArrayList<String> ignoreSuffix = new ArrayList<>();
		ignoreSuffix.add("_test");
		ProcessConfig processConfig = ProcessConfig.builder()
				//忽略表名
				.ignoreTableName(ignoreTableName)
				//忽略表前缀
				.ignoreTablePrefix(ignorePrefix)
				//忽略表后缀
				.ignoreTableSuffix(ignoreSuffix).build();
		//配置
		Configuration config = Configuration.builder()
				//版本
				.version("1.0.0")
				//描述
				.description("数据库设计文档生成")
				//数据源
				.dataSource(dataSource)
				//生成配置
				.engineConfig(engineConfig)
				//生成配置
				.produceConfig(processConfig).build();
		//执行生成
		new DocumentationExecute(config).execute();
		//由于会自动打开目录，所以不需要在此提示
		//Alerts(true, "文档已生成至：" +dir);
	}
	
	private static boolean check(Map<String,String> map){
		if(!map.containsKey("-n")||map.get("-n")==null||map.get("-n").equals("")){
    		Alerts(false,"请输入数据库名称！");
    		return false;
    	}
    	if(!map.containsKey("-u")||map.get("-u")==null||map.get("-u").equals("")){
    		Alerts(false,"请输入数据库用户名！");
    		return false;
    	}
    	if(!map.containsKey("-p")||map.get("-p")==null||map.get("-p").equals("")){
    		Alerts(false,"请输入数据库密码！");
    		return false;
    	}
    	if(!map.containsKey("-d")||map.get("-d")==null||map.get("-d").equals("")){
    		Alerts(false,"请输入保存文件的目录！");
    		return false;
    	}
    	return true;
	}
	
	
	public static void Alerts(boolean is,String content){
		Alert alert = new Alert(AlertType.INFORMATION);
		if(is){
			alert.setTitle("Dialog");	
			alert.setHeaderText(null);
			alert.setContentText(content);
		}else{
			alert.setTitle("Dialog");	
			alert.setHeaderText(null);
			alert.setContentText(content);
		}
		alert.showAndWait();
	}

}
